/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#ifndef LIB2D_HARD_RENDERER_H
#define LIB2D_HARD_RENDERER_H

#include <vector>
#include <ColorPacked.h>
#include <lib2d/math.h>
#include "ShiftStack.h"
#include <pictureformat/pictureformat.h>

namespace liba
{

class WindowImpl;

namespace lib2d
{

namespace hard
{

class Image;

class Renderer
{
public:
	virtual ~Renderer()
	{}

	virtual bool set_mode( WindowImpl * window_impl, int sx, int sy, bool fullscreen)=0;
	virtual void stop_mode()=0;

	virtual void flip()=0;

	virtual int get_height()const=0;
	virtual int get_width()const=0;

	virtual void start_scene( const Rect & rect )=0;
	virtual void finish_scene()=0;

	virtual pictureformat::Format get_format()const=0;
	virtual pictureformat::Format get_associated_format( pictureformat::Format format )const=0;

	virtual Image * create_image( int sx, int sy, pictureformat::Format format )=0;

	virtual void fill( const Rect & rect, const ColorPacked & color)=0;
	virtual void draw_rect( const Rect & rect, const ColorPacked & color )=0;
	virtual void draw_line( int x1, int y1, int x2, int y2, const ColorPacked & color )=0;

	virtual void set_gamma( int gamma )=0;

	void push_shift_add( const Vector2 & shift );
	void push_shift( const Vector2 & shift );
	void pop_shift();

	void push_clip_rect(const Rect & rect);
	void pop_clip_rect();

protected:
	std::vector<Rect> clip_rects;
	ShiftStack shifts;
};

inline void Renderer::push_shift_add( const Vector2 & shift )
{
	shifts.push_add( shift );
}

inline void Renderer::push_shift( const Vector2 & shift )
{
	shifts.push( shift );
}

inline void Renderer::pop_shift()
{
	shifts.pop();
}

inline void Renderer::push_clip_rect( const Rect & rect )
{
	if( clip_rects.size() > 0 )
	{
		Rect rect_translated( rect );
		rect_translated.shift( shifts.top() );
		rect_translated.intersect( clip_rects.back() );
		clip_rects.push_back( rect_translated );
	}
	else
		clip_rects.push_back( rect );
}

inline void Renderer::pop_clip_rect()
{
	if( clip_rects.size() )
		clip_rects.pop_back();
}

} //namespace hard
} //namespace lib2d
} //namespace liba

using namespace liba;

#endif //LIB2D_HARD_RENDERER2D_H
